use std::io::{Read, Write};
use std::net::{TcpListener, TcpStream};
use std::path::PathBuf;
use std::thread;

pub fn demo_http(dir: &str, addr: &str) {
    let listener = TcpListener::bind(addr).unwrap();
    let root_dir = PathBuf::from(dir);

    for stream in listener.incoming() {
        match stream {
            Ok(stream) => {
                let root_dir = root_dir.clone();
                thread::spawn(move || {
                    handle_client(stream, &root_dir);
                });
            }
            Err(e) => {
                println!("Error: {}", e);
            }
        }
    }
}

fn handle_client(mut stream: TcpStream, root_dir: &PathBuf) {
    let mut buffer = [0; 1024];
    stream.read(&mut buffer).unwrap();

    let request = String::from_utf8_lossy(&buffer[..]);
    let path = match get_path(&request) {
        Some(p) => p,
        None => return,
    };

    let file_path = root_dir.join(path.strip_prefix("/").unwrap());

    let response = if file_path.is_file() {
        let contents = std::fs::read_to_string(file_path).unwrap();
        format!(
            "HTTP/1.1 200 OK\r\nContent-Length: {}\r\n\r\n{}",
            contents.len(),
            contents
        )
    } else {
        "HTTP/1.1 404 NOT FOUND\r\n\r\n".to_string()
    };

    stream.write(response.as_bytes()).unwrap();
    stream.flush().unwrap();
}

fn get_path(request: &str) -> Option<&str> {
    let parts: Vec<&str> = request.split_whitespace().collect();
    if parts.len() < 3 || parts[0] != "GET" {
        return None;
    }

    Some(parts[1])
}
